﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Reflection;
using System.Collections;

namespace Jlob.OpenErpNet
{
    public static class OpenErpExtensions
    {
        public static IEnumerable<T> Include<T, TProperty>(this IEnumerable<T> source, Expression<Func<T, TProperty>> path) where T : class
        {
            OpenErpEnumerable<T> enumerable = source as OpenErpEnumerable<T>;
            OpenErpService service = enumerable.GetService();
            if (enumerable != null)
            {
                MemberExpression memberAccess = path.Body as MemberExpression;
                if (memberAccess!=null)
                {
                    MemberInfo member = memberAccess.Member as MemberInfo;
                    if (member != null)
                    {
                        //Search for openerpmap attribute
                        Type memberType = ((PropertyInfo)memberAccess.Member).PropertyType;
                        OpenErpMapAttribute[] attributes;
                        if (member != null)
                        {
                            attributes = (OpenErpMapAttribute[])memberType.GetCustomAttributes(typeof(OpenErpMapAttribute), false);
                            if (attributes.Length > 0)
                            {
                                //property type has a OpenErp mapped attribute
                                string name = attributes[0].OpenErpName;
                                //Get property that contains id, ex: user => userId;
                                string property = memberType.Name + "Id";
                                PropertyInfo idProperty = member.DeclaringType.GetProperties().Where(p => p.Name.Equals(property)).Single();
                                foreach (T item in enumerable)
                                {
                                    int id = (int)idProperty.GetValue(item, null);
                                    //Buscamos en OpenErp
                                    Object res = service.GetEntityById(memberAccess.Member as PropertyInfo, id);
                                    ((PropertyInfo)memberAccess.Member).SetValue(item, res, null);
                                }
                            }
                            else
                            {
                                throw new ArgumentException("Property type has not mapped to OpenErp entity. Please, use OpenErpMapAttribute");
                            }
                        }
                    }
                }
                else
                {
                    throw new ArgumentException("Not a valid property to include.");
                }
            }
            return source;
        }
    }
}
